// Created by: Peter KURNEV
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

#ifndef BOPDS_Interf_HeaderFile
#define BOPDS_Interf_HeaderFile

#include <IntTools_CommonPrt.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <BOPDS_VectorOfCurve.hxx>
#include <BOPDS_VectorOfPoint.hxx>

/**
 * The class BOPDS_Interf is is to store the information about
 * the interference between two shapes. 
 * The class BOPDS_Interf is root class 
 *
*/
//=======================================================================
//function : BOPDS_Interf
//purpose  : 
//=======================================================================
class BOPDS_Interf  {
 public:
  //
  /**
   * Sets the indices of interferred shapes
   * @param theIndex1
   *   index of the first shape
   * @param theIndex2
   *   index of the second shape
   */
  void SetIndices(const Standard_Integer theIndex1,
    const Standard_Integer theIndex2) {
    myIndex1=theIndex1; 
    myIndex2=theIndex2; 
  }
  //
  /**
   * Returns the indices of interferred shapes
   * @param theIndex1
   *   index of the first shape
   * @param theIndex2
   *   index of the second shape
   */
  void Indices(Standard_Integer& theIndex1,
        Standard_Integer& theIndex2) const {
   theIndex1=myIndex1; 
   theIndex2=myIndex2; 
        }
  //
  /**
   * Sets the index of the first interferred shape
   * @param theIndex
   *   index of the first shape 
   */
  void SetIndex1(const Standard_Integer theIndex) {
    myIndex1=theIndex; 
  }
  //
  /**
   * Sets the index of the second interferred shape
   * @param theIndex
   *   index of the second shape 
   */
  void SetIndex2(const Standard_Integer theIndex) {
    myIndex2=theIndex;
  }
  //
  /**
   * Returns the index of the first interferred shape
   * @return
   *   index of the first shape 
   */
  Standard_Integer Index1() const {
    return myIndex1; 
  }
  //
  /**
   * Returns the index of the second interferred shape
   * @return
   *   index of the second shape 
   */
  Standard_Integer Index2() const {
    return myIndex2; 
  }
  //
  /**
   * Returns the index of that are opposite to the given index
   * @param theI
   *   the index
   * @return
   *   index of opposite shape 
   */
  Standard_Integer OppositeIndex(const Standard_Integer theI) const {
    if (theI==myIndex1) {
      return myIndex2;
    }
    else if(theI==myIndex2) {
      return myIndex1;
    }
    else {
      return -1;
    }
  }
  //
  /**
   * Returns true if the interference contains given index
   * @param theIndex 
   *   the index
   * @return
   *   true if the interference contains given index
   */
  Standard_Boolean Contains(const Standard_Integer theIndex)const {
    return (myIndex1==theIndex || myIndex2==theIndex);
  }
  //
  /**
   * Sets the index of new shape 
   * @param theIndex 
   *   the index
   */
  void SetIndexNew(const Standard_Integer theIndex) {
    myIndexNew=theIndex;
  }
  //
  //
  /**
   * Returns the index of new shape 
   * @return theIndex 
   *   the index of new shape 
   */
  Standard_Integer IndexNew() const {
    return myIndexNew; 
  }
  //
  /**
   * Returns true if the interference has index of new shape
   * that is equal to the given index 
   * @param theIndex 
   *   the index
   * @return true if the interference has index of new shape
   * that is equal to the given index 
   */
  Standard_Boolean HasIndexNew(Standard_Integer& theIndex) const {
    theIndex=myIndexNew;
    return (myIndexNew>=0);
  }
  //
  /**
   * Returns true if the interference has index of new shape
   *   the index
   * @return true if the interference has index of new shape
   */
  Standard_Boolean HasIndexNew() const {
    return (myIndexNew+1) != 0;
  }
  //
 protected:     
  BOPDS_Interf() :
    myIndex1(-1), 
    myIndex2(-1),
    myIndexNew(-1),
    myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()) {
  }
  //
  BOPDS_Interf(const Handle(NCollection_BaseAllocator)& theAllocator) :
    myIndex1(-1), 
    myIndex2(-1),
    myIndexNew(-1),
    myAllocator(theAllocator) {
  }
  //
  virtual ~BOPDS_Interf() {
  }
  
 protected:   
  Standard_Integer myIndex1;
  Standard_Integer myIndex2;
  Standard_Integer myIndexNew;
  Handle(NCollection_BaseAllocator) myAllocator;
};
/**
 * The class BOPDS_InterfVV is is to store the information about
 * the interference of the type vertex/vertex. 
*/
//=======================================================================
//function : BOPDS_InterfVV
//purpose  : 
//=======================================================================
class BOPDS_InterfVV  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfVV() : BOPDS_Interf() {
  }
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfVV(const Handle(NCollection_BaseAllocator)& theAllocator) 
    : BOPDS_Interf(theAllocator) {
  }
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfVV() {
  }
  //
};
/**
 * The class BOPDS_InterfVE is is to store the information about
 * the interference of the type vertex/edge. 
*/
//=======================================================================
//function : BOPDS_InterfVE
//purpose  : 
//=======================================================================
class BOPDS_InterfVE  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfVE() 
    :
      BOPDS_Interf(),
      myParameter(0.) {
  }
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfVE(const Handle(NCollection_BaseAllocator)& theAllocator) 
    :
      BOPDS_Interf(theAllocator),
      myParameter(0.) {
  }
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfVE() {
  }
  //
  /**
   *  Modifier
   * Sets the value of parameter 
   * of the point of the vertex 
   * on the curve of the edge
   * @param theT
   *   value of parameter 
   */
  void SetParameter(const Standard_Real theT) {
    myParameter=theT;
  }
  //
  /**
   *  Selector
   * Returrns the value of parameter 
   * of the point of the vertex 
   * on the curve of the edge
   * @return
   *   value of parameter 
   */
  Standard_Real Parameter() const {
    return myParameter;
  }
  
 protected:
  Standard_Real myParameter;
  
};
/**
 * The class BOPDS_InterfVF is is to store the information about
 * the interference of the type vertex/face 
*/
//=======================================================================
//function : BOPDS_InterfVF
//purpose  : 
//=======================================================================
class BOPDS_InterfVF  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfVF()
    : BOPDS_Interf(),
      myU(0.),
      myV(0.) {
  }
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfVF(const Handle(NCollection_BaseAllocator)& theAllocator)
    : BOPDS_Interf(theAllocator),
      myU(0.),
      myV(0.) {
  }
  //
  /**
   *  Destructor
   */  
  virtual ~BOPDS_InterfVF() {
  }
  //
  /**
   * Modifier
   * Sets the value of parameters 
   * of the point of the vertex 
   * on the surface of of the face
   * @param theU
   *   value of U parameter
   * @param theV 
   *   value of U parameter 
   */
  void SetUV(const Standard_Real theU,
      const Standard_Real theV) {
    myU=theU;
    myV=theV;
  }
  //
  /**
   * Selector
   * Returns the value of parameters 
   * of the point of the vertex 
   * on the surface of of the face
   * @param theU
   *   value of U parameter
   * @param theV 
   *   value of U parameter 
   */
  void UV(Standard_Real& theU,Standard_Real& theV) const {
    theU=myU;
    theV=myV;
  }
  
 protected:
  Standard_Real myU;
  Standard_Real myV;
      
};
/**
 * The class BOPDS_InterfEE is is to store the information about
 * the interference of the type edge/edge. 
*/
//=======================================================================
//function : BOPDS_InterfEE
//purpose  : 
//=======================================================================
class BOPDS_InterfEE  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfEE() : BOPDS_Interf() {
  }
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfEE(const Handle(NCollection_BaseAllocator)& theAllocator)
    : BOPDS_Interf(theAllocator) {
  }
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfEE() {
  }
  //
  /**
   *  Modifier
   * Sets the info of common part 
   * @param theCP
   *   common part
   */
  void SetCommonPart(const IntTools_CommonPrt& theCP) {
    myCommonPart=theCP;
  }
  //
  /**
   *  Selector
   * Returns the info of common part 
   * @return
   *   common part
   */
  const IntTools_CommonPrt& CommonPart() const {
    return myCommonPart;
  }
  
 protected:
  IntTools_CommonPrt myCommonPart;
};
/**
 * The class BOPDS_InterfEF is is to store the information about
 * the interference of the type edge/face. 
*/
//=======================================================================
//function : BOPDS_InterfEF
//purpose  : 
//=======================================================================
class BOPDS_InterfEF  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfEF(): BOPDS_Interf() {
  }
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfEF(const Handle(NCollection_BaseAllocator)& theAllocator)
    : BOPDS_Interf(theAllocator) {
  }
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfEF() {
  }
  //
  /**
   * Modifier
   * Sets the info of common part 
   * @param theCP
   *   common part
   */
  void SetCommonPart(const IntTools_CommonPrt& theCP){
    myCommonPart=theCP;
  }
  //
  /**
   *  Selector
   * Returns the info of common part 
   * @return
   *   common part
   */
  const IntTools_CommonPrt& CommonPart() const {
    return myCommonPart;
  }
  //
 protected:
  IntTools_CommonPrt myCommonPart;
}
/**
 * The class BOPDS_InterfFF is is to store the information about
 * the interference of the type face/face. 
*/;
//=======================================================================
//function : BOPDS_InterfFF
//purpose  : 
//=======================================================================
class BOPDS_InterfFF  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfFF()
    : 
      BOPDS_Interf(),
      myTangentFaces(Standard_False),
      myCurves(0, myAllocator),
      myPoints(0, myAllocator) 
  {
  }
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfFF() {
  }
  //
  /**
   * Initializer
   * @param theNbCurves
   *   number of intersection curves
   * @param theNbPoints
   *   number of intersection points
   */
  
  void Init(const Standard_Integer theNbCurves,
            const Standard_Integer theNbPoints) {
    if (theNbCurves>0) {
      myCurves.SetIncrement(theNbCurves);
    }
    if (theNbPoints>0) {
      myPoints.SetIncrement(theNbPoints);
    }
  }
  /**
   * Modifier
   * Sets the flag of whether the faces are tangent  
   * @param theFlag
   *   the flag 
   */
  void SetTangentFaces(const Standard_Boolean theFlag) {
     myTangentFaces=theFlag;
  }
  /**
   * Selector
   * Returns the flag whether the faces are tangent  
   * @return
   *   the flag 
   */
  Standard_Boolean TangentFaces()const {
    return myTangentFaces;
  }
  //
  /**
   * Selector
   * Returns the intersection curves  
   * @return
   *   intersection curves 
   */
  const BOPDS_VectorOfCurve& Curves()const{
    return myCurves;
  }
  //
  /**
   * Selector/Modifier
   * Returns the intersection curves  
   * @return
   *   intersection curves 
   */
  BOPDS_VectorOfCurve& ChangeCurves(){
    return myCurves;
  }
  //
  /**
   * Selector
   * Returns the intersection points  
   * @return
   *   intersection points
   */
  const BOPDS_VectorOfPoint& Points()const{
    return myPoints;
  }
  //
  /**
   * Selector/Modifier
   * Returns the intersection points  
   * @return
   *   intersection points
   */
  BOPDS_VectorOfPoint& ChangePoints(){
    return myPoints;
  }
  //
 protected:
  Standard_Boolean myTangentFaces;
  BOPDS_VectorOfCurve myCurves;
  BOPDS_VectorOfPoint myPoints;
};

/**
 * The class BOPDS_InterfVZ is is to store the information about
 * the interference of the type vertex/solid. 
*/
//=======================================================================
//function : BOPDS_InterfVZ
//purpose  : 
//=======================================================================
class BOPDS_InterfVZ  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfVZ() : BOPDS_Interf() {
  };
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfVZ(const Handle(NCollection_BaseAllocator)& theAllocator) 
    : BOPDS_Interf(theAllocator) {
  };
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfVZ() {
  };
  //
};
/**
 * The class BOPDS_InterfEZ is is to store the information about
 * the interference of the type edge/solid. 
*/
//=======================================================================
//function : BOPDS_InterfEZ
//purpose  : 
//=======================================================================
class BOPDS_InterfEZ  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfEZ() : BOPDS_Interf() {
  };
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfEZ(const Handle(NCollection_BaseAllocator)& theAllocator) 
    : BOPDS_Interf(theAllocator) {
  };
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfEZ() {
  };
  //
};
/**
 * The class BOPDS_InterfFZ is is to store the information about
 * the interference of the type face/solid. 
*/
//=======================================================================
//function : BOPDS_InterfFZ
//purpose  : 
//=======================================================================
class BOPDS_InterfFZ  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfFZ() : BOPDS_Interf() {
  };
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfFZ(const Handle(NCollection_BaseAllocator)& theAllocator) 
    : BOPDS_Interf(theAllocator) {
  };
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfFZ() {
  };
  //
};
/**
 * The class BOPDS_InterfZZ is is to store the information about
 * the interference of the type solid/solid. 
*/
//=======================================================================
//function : BOPDS_InterfZZ
//purpose  : 
//=======================================================================
class BOPDS_InterfZZ  : public BOPDS_Interf {
 public:
  //
  /**
   *  Constructor
   */
  BOPDS_InterfZZ() : BOPDS_Interf() {
  };
  //
  /**
   *  Constructor
   * @param theAllocator
   *   allocator to manage the memory
   */
  BOPDS_InterfZZ(const Handle(NCollection_BaseAllocator)& theAllocator) 
    : BOPDS_Interf(theAllocator) {
  };
  //
  /**
   *  Destructor
   */
  virtual ~BOPDS_InterfZZ() {
  };
  //
};

#endif
